#include "RingQueue.hpp"
#include "Task.hpp"

#include <pthread.h>
#include <time.h>
#include <unistd.h>

#define NUM 5

void *consumer(void *args)
{
    // MyRingQueue::RingQueue<int> *rq = (MyRingQueue::RingQueue<int> *)args;
    // while (true)
    // {
    //     int data = 0;
    //     rq->Pop(&data);
    //     std::cout << "Consumer " << pthread_self() << " get data from RingQueue:" << data << std::endl;
    //     sleep(2);
    // }
    /*-------------------------------------------------------------------------*/
    MyRingQueue::RingQueue<MyTask::Task> *rq = (MyRingQueue::RingQueue<MyTask::Task> *)args;
    while (true)
    {
        MyTask::Task t;
        rq->Pop(&t);
        std::cout << "Consumer " << pthread_self() << " get data from RingQueue->";
        t();
        sleep(2);
    }
}

void *productor(void *args)
{
    // MyRingQueue::RingQueue<int> *rq = (MyRingQueue::RingQueue<int> *)args;
    // while (true)
    // {
    //     int data = rand() % 20 + 1;
    //     std::cout << "Productor " << pthread_self() << " push data to RingQueue:" << data << std::endl;
    //     rq->Push(data);
    //     sleep(2);
    // }
    /*-------------------------------------------------------------------------*/
    MyRingQueue::RingQueue<MyTask::Task> *rq = (MyRingQueue::RingQueue<MyTask::Task> *)args;
    const std::string ops = "+-*/%";
    while (true)
    {
        int x = rand() % 20 + 1;
        int y = rand() % 10 + 1;
        int op = ops[rand() % 5];
        MyTask::Task t(x, y, op);
        std::cout << "Productor " << pthread_self() << " push data to RingQueue->";
        rq->Push(t);
        t.Show();
        sleep(2);
    }
}

int main()
{
    srand((long long)time(nullptr));
    /*-------------------------------------------------------------------------*/
    // 创建交易场所————环形队列
    // MyRingQueue::RingQueue<int> *rq = new MyRingQueue::RingQueue<int>();
    // 创建线程————生产者消费者
    // pthread_t consumer_id, productor_id;

    // pthread_create(&consumer_id, nullptr, consumer, (void*)rq);
    // pthread_create(&productor_id, nullptr, productor, (void*)rq);

    // pthread_join(consumer_id, nullptr);
    // pthread_join(productor_id, nullptr);

    // return 0;
    /*-------------------------------------------------------------------------*/
    // 创建交易场所————环形队列
    MyRingQueue::RingQueue<MyTask::Task> *rq = new MyRingQueue::RingQueue<MyTask::Task>();
    // 创建线程————多生产者多消费者
    pthread_t consumer_id[NUM], productor_id[NUM];

    for (int i = 0; i < NUM; ++i)
    {
        pthread_create(consumer_id + i, nullptr, consumer, (void *)rq);
        pthread_create(productor_id + i, nullptr, productor, (void *)rq);
    }

    for (int i = 0; i < NUM; ++i)
    {
        pthread_join(consumer_id[i], nullptr);
        pthread_join(productor_id[i], nullptr);
    }

    return 0;
}